﻿#region

using System;
using System.Web;
using System.Web.SessionState;
using HouseHoldBudget.Core.Authentication;
using HouseHoldBudget.Framework.Session;

#endregion

namespace HouseHoldBudget.Framework.Authentication
{
    /// <summary>
    ///   Module d'authentification idesktop
    /// </summary>
    public sealed class BudgetAuthenticationModule : IHttpModule, IRequiresSessionState
    {
        #region Instance Properties

        /// <summary>
        ///   Gets the name of the module.
        /// </summary>
        /// <value> The name of the module. </value>
        public string ModuleName
        {
            get
            {
                return "HouseHoldAuthenticationModule";
            }
        }

        #endregion

        #region Event Handling

        /// <summary>
        ///   Handles the PostMapRequestHandler event of the Application control.
        /// </summary>
        /// <param name="source"> The source of the event. </param>
        /// <param name="e"> The <see cref="System.EventArgs" /> instance containing the event data. </param>
        private void Application_PostMapRequestHandler(object source, EventArgs e)
        {
            HttpApplication app = (HttpApplication) source;

            if (app.Context.Handler is IReadOnlySessionState || app.Context.Handler is IRequiresSessionState)
            {
                // no need to replace the current handler
                return;
            }

            // swap the current handler
            app.Context.Handler = new MyHttpHandler(app.Context.Handler);
        }

        /// <summary>
        ///   Handles the PostAcquireRequestState event of the context control.
        /// </summary>
        /// <param name="sender"> The source of the event. </param>
        /// <param name="e"> The <see cref="System.EventArgs" /> instance containing the event data. </param>
        private void context_PostAcquireRequestState(object sender, EventArgs e)
        {
            HttpApplication application = (HttpApplication) sender;
            HttpContext context = application.Context;

            try
            {
                //Check if session state if required
                MyHttpHandler resourceHttpHandler = HttpContext.Current.Handler as MyHttpHandler;
                if (resourceHttpHandler != null)
                {
                    // set the original handler back
                    HttpContext.Current.Handler = resourceHttpHandler.OriginalHandler;
                }

                BudgetIdentity budgetUserIdentity = null;

                if (String.Compare(context.Request.CurrentExecutionFilePath, BudgetFormsAuthenticationService.LoginUrl, true) != 0)
                {
                    budgetUserIdentity = SessionPersister.CurrentBudgetUserIdentity;
                    if (budgetUserIdentity == null)
                    {
                        if (context.Request.LogonUserIdentity != null)
                        {
                            string userLoginWithoutDomain =
                                context.Request.LogonUserIdentity.Name.Split('\\')[1];
                            budgetUserIdentity = BudgetAuthenticationHelper.ValidateUser(userLoginWithoutDomain);
                            if (budgetUserIdentity.CurrentUser != null)
                            {
                                BudgetFormsAuthenticationService.SetAuthentication(budgetUserIdentity);
                                HttpContext.Current.User = new UserPrincipal(budgetUserIdentity);
                            }
                        }
                    }
                }

                //Set user in the http context
                if (budgetUserIdentity.CurrentUser != null)
                {
                    HttpContext.Current.User = new UserPrincipal(budgetUserIdentity);
                }
                else
                {
                    HttpContext.Current.User = new UserPrincipal(BudgetIdentity.GetAnonymous());
                }
            }
            catch (Exception ex)
            {
                //LoggerManager.GetBusinessLogger.LogError("AuthenticationModule - PostAcquireRequestState failed - " + ex.ToString());
            }
        }

        #endregion

        #region IHttpModule Members

        /// <summary>
        ///   Disposes of the resources (other than memory) used by the module that implements <see cref="T:System.Web.IHttpModule" /> .
        /// </summary>
        public void Dispose()
        {
        }

        /// <summary>
        ///   Init Module
        /// </summary>
        /// <param name="context"> An <see cref="T:System.Web.HttpApplication" /> that provides access to the methods, properties, and events common to all application objects within an ASP.NET application </param>
        public void Init(HttpApplication context)
        {
            BudgetFormsAuthenticationService.Initialize();
            context.PostAcquireRequestState += context_PostAcquireRequestState;
            context.PostMapRequestHandler += Application_PostMapRequestHandler;
        }

        #endregion
    }


    public class MyHttpHandler : IHttpHandler, IRequiresSessionState
    {
        #region Readonly & Static Fields

        internal readonly IHttpHandler OriginalHandler;

        #endregion

        #region Constructors

        public MyHttpHandler(IHttpHandler originalHandler)
        {
            OriginalHandler = originalHandler;
        }

        #endregion

        #region IHttpHandler Members

        public void ProcessRequest(HttpContext context)
        {
            throw new InvalidOperationException("MyHttpHandler cannot process requests.");
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }

        #endregion
    }
}